home *** CD-ROM | disk | FTP | other *** search
- ;* GCSWEEP.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Scan all pages and move objects to relocate *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL medium
- LOCALS @@
-
- INCLUDE "scheme.ash"
-
- CODESEG
-
- ;************************************************************************
- ;* gcsweep *
- ;************************************************************************
- PROC C gcsweep USES si di
- push ds ; set es to point to the current DS
- pop es
- mov ax, END_LIST
- mov cx, NUMTYPES
- lea di, [pagelist] ; load table address
- cld
- rep stosw ; initialize the pagelist table
- mov dx, NUMPAGES
- @@loop:
- dec dx
- cmp dx, DEDPAGES-1
- ja @@more
- ret
-
- @@more:
- push dx
- call swpage C, dx ; "sweep" the page (GC it)
- pop dx
- mov bx, dx ; use current page number as index
- sal bx, 1
- test [attrib+bx], NOMEMORY ; is page frame allocated?
- jnz @@loop
- mov ax, dx
- mov si, [WORD ptype+bx]
- xchg [pagelist+si], ax ; pagelist[type] <- page
- mov [pagelink+bx], ax ; pagelink[page] <- old pagelist[type]
- jmp @@loop
- ENDP gcsweep
-
- ;************************************************************************
- ;* swpage *
- ;************************************************************************
- PROC C swpage USES si di, @@pageno:WORD
- mov bx, [@@pageno] ; current page allocated ?
- sal bx, 1
- test [attrib+bx], NOMEMORY ; allocated?
- jz @@proceed
- @@fixnum: ; Fixnums & chars handled as immediates
- @@char:
- @@free: ; Why are we processing a free page?
- @@return:
- ret
-
- @@proceed:
- mov di, [WORD ptype+bx] ; Dispatch on the page type
- cmp di, FREETYPE
- je @@free
- ldpage es, bx ; define base paragraph for this page
- jmp [@@table+di]
- DATASEG
- @@table DW @@list ; [0] List cells
- DW @@fixnum ; [1] Fixnums
- DW @@flonum ; [2] Flonums
- DW @@bignum ; [3] Bignums
- DW @@symbol ; [4] Symbols
- DW @@string ; [5] Strings
- DW @@array ; [6] Arrays
- DW @@continuation ; [7] Continuations
- DW @@closure ; [8] Closures
- DW @@free ; [9] Free space (unallocated)
- DW @@code ; [10] Code
- DW @@inline ; [11] Inline code
- DW @@port ; [12] Port data objects
- DW @@char ; [13] Characters
- DW @@environment ; [14] Environments
- CODESEG
-
- @@list: ; List Cells & fixed length pointer objects
- mov ax, SIZE LISTDEF
- xor si, si
- xor di, di ; zero referenced cell counter
- mov cx, END_LIST
- mov dl, SPECFREE*2
- push bx ; save page number index
- mov bx, [psize+bx]
- sub bx, ax ; adjust length for boundary check
- @@listloop:
- test [(LISTDEF es:si).gc], GC_BIT
- jnz @@listmarked
- mov [(FREELISTDEF es:si).next], cx
- mov [(FREELISTDEF es:si).tag], dl
- mov cx, si
- jmp @@listnext
- @@listmarked:
- and [(LISTDEF es:si).gc], NOT GC_BIT
- inc di ; increment referenced cell counter
- @@listnext:
- add si, ax
- cmp si, bx ; test for end of page
- jbe @@listloop
- ; end of page update free list header
- pop bx ; restore page table index
- mov [nextcell+bx], cx
- or di, di ; any referenced cells in this page?
- jnz @@return
- mov [ptype+bx], FREETYPE ; mark empty page as free
- mov [attrib+bx], 0
- jmp @@return
-
- @@flonum: ; Process Page of Flonums
- mov ax, SIZE FLODEF
- xor si, si
- xor di, di ; zero referenced cell counter
- mov cx, END_LIST
- mov dl, FREETYPE
- push bx ; save page number index
- mov bx, [psize+bx]
- sub bx, ax ; adjust for boundary check
- @@floloop:
- cmp [(FLODEF es:si).tag], dl ; tag = free?
- je @@flofree
- test [(FLODEF es:si).gc], GC_BIT
- jnz @@flomarked
- mov [(FREEFLODEF es:si).tag], dl
- @@flofree:
- mov [(FREEFLODEF es:si).next], cx
- mov cx, si
- jmp @@flonext
- @@flomarked:
- and [(FLODEF es:si).gc], NOT GC_BIT
- inc di ; increment referenced cell counter
- @@flonext:
- add si, ax
- cmp si, bx ; test for end of page
- jbe @@floloop
- ; end of page update free flo header
- pop bx ; restore page table index
- mov [nextcell+bx], cx
- or di, di ; any referenced cells in this page?
- jnz @@floreturn
- mov [ptype+bx], FREETYPE ; mark empty page as free
- mov [attrib+bx], 0
- @@floreturn:
- jmp @@return
-
- @@bignum: ; Process variable length data object
- @@symbol:
- @@string:
- @@inline:
- @@array:
- @@closure:
- @@continuation:
- @@code:
- @@environment:
- xor si, si
- mov di, -1
- push bx ; save page table index
- mov bx, [psize+bx]
- sub bx, SIZE POINTER ; adjust size for boundary check
- @@dataloop:
- mov dx, [(ANYDEF es:si).len]
- or dx, dx
- jge @@bigstr
- mov dx, OFFSET (TYPE STRDEF).buffer + SIZE POINTER
- @@bigstr:
- test [(ANYDEF es:si).gc], GC_BIT
- jnz @@datamarked
- or di, di ; Combine with previous free area ?
- jge @@datacombine
- mov [(ANYDEF es:si).tag], FREETYPE
- mov [(ANYDEF es:si).len], dx
- mov di, si ; Remember object not referenced
- jmp @@datanext
- @@datacombine:
- add [(ANYDEF es:di).len], dx
- jmp @@datanext
- @@datamarked:
- and [(ANYDEF es:si).gc], NOT GC_BIT
- mov di, -1 ; Remember last object was referenced
- @@datanext:
- add si, dx ; Increment area pointer by block length
- cmp si, bx ; Last object in block?
- jb @@dataloop
- @@finished:
- pop bx
- or di, di ; last block free ?
- jl @@lastnotfree
- sub si, [psize+bx] ; Adjust in case last byte of page not accounted for
- neg si
- add [(ANYDEF es:di).len], si
- mov [nextcell+bx], di ; Update free pool header
- or di, di ; is page empty?
- jnz @@datareturn
- mov [ptype+bx], FREETYPE ; mark page as being free
- mov [attrib+bx], 0
- cmp bl, [emsbias] ; is this page in EMS ? if so, it
- jae @@smallpage ; can't be a big page
- mov ax, [psize+bx]
- cmp ax, [defpagesize]
- ja @@fixbig
- @@smallpage:
- jmp @@return
- @@lastnotfree:
- mov [nextcell+bx], END_LIST ; Indicate no free pool
- @@datareturn:
- jmp @@return
-
- @@port: ; ports -- close any open files
- xor si, si
- mov di, -1
- push bx ; save page table index
- mov bx, [psize+bx]
- sub bx, SIZE POINTER ; adjust size for boundary check
- @@portloop:
- mov dx, [(PORTDEF es:si).len]
- test [(PORTDEF es:si).gc], GC_BIT
- jnz @@portmarked
- cmp [(PORTDEF es:si).tag], FREETYPE
- je @@portok
- test [(PORTDEF es:si).pflags], PORT_OPEN ; open ?
- jz @@portok
- push bx dx
- mov bx, [(PORTDEF es:si).pflags]
- and bx, PORT_TYPE
- cmp bx, TYPE_FILE
- jne @@noclose
- mov bx, [(PORTDEF es:si).handle] ; close file
- call close C, bx
- @@noclose:
- pop dx bx
- @@portok: ; combine with previous free area?
- or di, di
- jge @@portcombine
- mov [(PORTDEF es:si).tag], FREETYPE
- mov di, si ; remember object not referenced
- jmp @@portnext
- @@portcombine:
- add [(PORTDEF es:di).len], dx
- jmp @@portnext
- @@portmarked:
- and [(PORTDEF es:si).gc], NOT GC_BIT
- mov di, -1 ; Remember last object was referenced
- @@portnext:
- add si, dx ; Increment area pointer by block length
- cmp si, bx ; Last object in block?
- jb @@portloop
- jmp @@finished
-
- @@fixbig: ; Restore memory management tables due
- ; to release of large page
- mov cx, [defpagesize]
- mov ax, cx ; page size of large page <- default
- xchg ax, [psize+bx]
- ldpage dx, bx ; load para address of large page
- mov bx, cx
- shr cx, 1 ; cx <- pagesize/16
- shr cx, 1
- shr cx, 1
- shr cx, 1
- @@fixloop:
- sub ax, bx ; decrease big page size by one page
- jbe @@fixreturn
- add dx, cx ; compute pointer to next physical page
- mov si, DEDPAGES*2 ; initialize page table index
- @@fixmore:
- ldpage di, si ; is this the page we're looking for?
- cmp dx, di
- je @@fixfound
- add si, 2 ; increment the page table index
- cmp si, NUMPAGES*2 ; more pages?
- jl @@fixmore
- lea bx, [@@msg] ; error-- loop should not exit
- DATASEG
- @@msg DB "[VM INTERNAL ERROR] swpage: logical page not found", LF, 0
- CODESEG
- call print_and_exit C, bx ; print error message and exit
- @@fixfound:
- mov [psize+si], bx ; reset page size to default
- mov [attrib+si], 0 ; reset "no memory" bit in attribute table
- mov [ptype+si], FREETYPE ; mark page as free
- jmp @@fixloop
- @@fixreturn:
- jmp @@return
- ENDP swpage
-
- END
-